//
//  STSportingManager.m
//  STBest
//
//  Created by apple on 2017/8/28.
//  Copyright © 2017年 apple. All rights reserved.
//

#import "STSportingManager.h"
#import <CoreLocation/CoreLocation.h>
@interface STSportingManager()<CLLocationManagerDelegate>

//位置管理器
@property(strong, nonatomic)  CLLocationManager               *mgr;

@property(assign, nonatomic)  STSportingState                 state;

@property (assign, nonatomic) STSportingGPSState              gpsState;

@end
@implementation STSportingManager{
    
    NSMutableArray<STSportingTracking *>           *_sportingTrackings;
    
    STSportingTracking                             *_sportingsportingTracking;
    
    // 开始运动时间
    NSTimeInterval                                  _beginSportingTimeInterval;
}


//单例
+ (STSportingManager *)sharedInstance{
    static dispatch_once_t onceToken;
    static STSportingManager *__instance__;
    dispatch_once(&onceToken, ^{
        __instance__ = [STSportingManager new];
    });
    
    return __instance__;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        _sportingTrackings = [NSMutableArray array];
        
        self.state = STSportingStateUnsport;
        
        [self setupLocationManager];
        
        // kvo 监听运动状态
        [self addObserver:self forKeyPath:@"state" options:NSKeyValueObservingOptionNew context:NULL];
        [self addObserver:self forKeyPath:@"gpsState" options:NSKeyValueObservingOptionNew context:NULL];
    }
    return self;
}

#pragma mark - 核心位置管理 -
- (void)setupLocationManager {
    
    self.mgr = [CLLocationManager new];
    
    // 请求用户授权 需要配置 Info.plist 添加key
    [self.mgr requestWhenInUseAuthorization];
    
     // 设置支持iOS9 后台运行 需要注意 工程文件配置
    if([self.mgr respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]){
        
        self.mgr.allowsBackgroundLocationUpdates = YES;
    }
    
    self.mgr.delegate = self;
    
    //开启
    [self.mgr startUpdatingLocation];
}

#pragma mark - 运动管理 -
// 添加一个运动
- (void)addSportingTracking:(STSportingTracking *)sportingTracking{
    
    [_sportingTrackings addObject:sportingTracking];
}

// 删除一个运动
- (void)removeSportingTracking:(STSportingTracking *)sportingTracking{
    
    [_sportingTrackings removeObject:sportingTracking];
}

#pragma mark - 运动控制 -
// 开始运动
- (void)startWithType:(STSportingTrackingType)type{
    if(_sportingsportingTracking == nil){
        
        _sportingsportingTracking = [STSportingTracking new];
        _sportingsportingTracking.type = type;
        
    }
    self.state = STSportingStateSporting;
    
    // 触发运动开始事件
    [[NSNotificationCenter defaultCenter] postNotificationName:STSportingEventTriggerNotification object:self userInfo:@{kSportEvent:@(STSportingEventBegin)}];
    
    // 设置开始运动的时间
    _beginSportingTimeInterval = [NSDate date].timeIntervalSince1970;
    
}

// 暂停运动
- (void)pause{
    
    self.state = STSportingStatePaused;
    
    // 触发运动开始事件
    [[NSNotificationCenter defaultCenter] postNotificationName:STSportingEventTriggerNotification object:self userInfo:@{kSportEvent:@(STSportingEventPause)}];
}

// 继续运动
- (void)resume{
    
    self.state = STSportingStateSporting;
    
    // 触发运动开始事件
    [[NSNotificationCenter defaultCenter] postNotificationName:STSportingEventTriggerNotification object:self userInfo:@{kSportEvent:@(STSportingEventResume)}];
}

// 取消运动
- (void)cancel{
    
     self.state = STSportingStateUnsport;
    
    // 触发运动开始事件
    [[NSNotificationCenter defaultCenter] postNotificationName:STSportingEventTriggerNotification object:self userInfo:@{kSportEvent:@(STSportingEventCancel)}];
    
    _sportingsportingTracking = nil;
    
    
}

// 完成运动
- (void)finish{
    
    if(_sportingsportingTracking != nil){
        [_sportingTrackings addObject:_sportingsportingTracking];
        
        _sportingsportingTracking = nil;
    }
    // 触发运动开始事件
    [[NSNotificationCenter defaultCenter] postNotificationName:STSportingEventTriggerNotification object:self userInfo:@{kSportEvent:@(STSportingEventEnd)}];
    
    self.state = STSportingStateUnsport;
}


#pragma mark - CLLocationManagerDelegate -
- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation{
    // 过滤 old 为 nil
    if(oldLocation == nil) {
        return;
    }
    
    // 过滤 两个时间差值为负数
    NSTimeInterval offset = newLocation.timestamp.timeIntervalSince1970 - oldLocation.timestamp.timeIntervalSince1970;
    if(offset < 0) return;
    
    /*
     如果时间差 <  1.1 信号好
     < 5 信号一般
     > 5 信号差
     
     */
    if(offset < 1.1) {
        if(self.gpsState != STSportingGPSStateGood) self.gpsState = STSportingGPSStateGood;
    } else if(offset < 5) {
        if(self.gpsState != STSportingGPSStateNormal) self.gpsState = STSportingGPSStateNormal;
    } else {
        if(self.gpsState != STSportingGPSStateBad) self.gpsState = STSportingGPSStateBad;
    }
    
    // 过滤 获取位置对象的时间不应该比开始运动时间小
    if(newLocation.timestamp.timeIntervalSince1970 < _beginSportingTimeInterval) {
        return;
    }

    
    //如果存在并且正在运动就记录
    if(_sportingsportingTracking != nil && self.state == STSportingStateSporting){
        STSportingTrackingLine *line = [STSportingTrackingLine new];
        line.beginLocation = oldLocation;
        line.endLocation = newLocation;
        
        [_sportingsportingTracking.lines addObject:line];
        
        [[NSNotificationCenter defaultCenter] postNotificationName:STSporingTrackingLineDidBeGeneratedNotification object:self userInfo:@{kSporingTrackingLine:line}];
    }
}

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{
    /*
     // 未决定
     kCLAuthorizationStatusNotDetermined = 0,
     
     // 受限制
     kCLAuthorizationStatusRestricted,
     
     // 拒绝
     kCLAuthorizationStatusDenied,
     
     // 总是授权
     kCLAuthorizationStatusAuthorizedAlways NS_ENUM_AVAILABLE(10_12, 8_0),
     
     // 试用期间授权
     kCLAuthorizationStatusAuthorizedWhenInUse NS_ENUM_AVAILABLE(NA, 8_0),
     
     // 已授权
     kCLAuthorizationStatusAuthorized NS_ENUM_DEPRECATED(10_6, NA, 2_0, 8_0, "Use kCLAuthorizationStatusAuthorizedAlways") __TVOS_PROHIBITED __WATCHOS_PROHIBITED = kCLAuthorizationStatusAuthorizedAlways
     */
    
    if(status == kCLAuthorizationStatusAuthorized || status == kCLAuthorizationStatusAuthorizedAlways || status == kCLAuthorizationStatusAuthorizedWhenInUse) {
        self.state =STSportingGPSStateGood;
        // 触发运动开始事件
        [[NSNotificationCenter defaultCenter] postNotificationName:STSportingEventTriggerNotification object:self userInfo:@{kSportEvent:@(STSportingEventGPSEnable)}];
    } else {
        self.gpsState = STSportingGPSStateDisconnect;
        // 触发运动开始事件
        [[NSNotificationCenter defaultCenter] postNotificationName:STSportingEventTriggerNotification object:self userInfo:@{kSportEvent:@(STSportingEventGPSDisenable)}];
    }

}

#pragma mark - KVO -
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    if([keyPath isEqualToString:@"state"]){
        
        [[NSNotificationCenter defaultCenter] postNotificationName:STSportingStateDidChangedNotification object:self userInfo:@{kState:change[NSKeyValueChangeNewKey]}];
    }else if([keyPath isEqualToString:@"gpsState"]){
        [[NSNotificationCenter defaultCenter] postNotificationName:STSportingGPSStateDidChangedNotification object:self userInfo:@{kGPSState:change[NSKeyValueChangeNewKey]}];
    }
}

@end
